import java.util.Hashtable;
import java.util.Enumeration;
import java.util.StringTokenizer;
public class GGraph extends Graph
  {
  private Circle pointer;
  private Transition transition;
  private final int R=36;
  private int type=2;

  public GGraph(Machine machine)
    {
    super(machine);
    pointer=new Circle(0,0,0);
    }
  public Circle getCircle(String c)
    {
    return (Circle)getState(c);
    }
  public String getLabel()
    {
    return getSelected().getLabel();
    }
  public Enumeration circles()
    {
    return states();
    }
  public Circle getStart()
    {
    return (Circle)super.getStart();
    }
  public void setStart(Circle start)
    {
    super.setStart((State)start);
    }
  public Circle getSelected()
    {
    return (Circle)super.getSelected();
    }
  public Circle getCircle(int x,int y)
    {
    Circle c=null;
    Enumeration cs=keys();
    while(cs.hasMoreElements())
      {
      c=(Circle)cs.nextElement();
      if(c.contains(x,y)) return c;
      }
    return null;
    }
  public void setSelected(int x,int y) 
    {
    super.setSelected((State)getCircle(x,y));
    }
  public void unselectSelected()
    {
    super.setSelected(null);
    }
  private int dx;
  private int dy;
  private boolean movable=false;
  public void addOrSelectCircle(int x,int y)
    {
    movable=false;
    if(isLocked())
      {
      setSelected(x,y);
      if(getSelected()==null)
        {
        setSelected(new Circle(x,y,R));
        addState(getSelected());
        }
      movable=true;
      }
    else if(getSelected().contains(x,y))
      {
      movable=true;
      }
    dx=x-getSelected().getX();
    dy=y-getSelected().getY();
    }
  public void setCirclePosition(int x,int y)
    {
    Circle selected=getSelected();
    if(selected!=null&&movable)
      {
      if(x>=dx) selected.setX(x-dx);
      if(y>=dy) selected.setY(y-dy);
      }
    }
  public void setPointerPosition(int x,int y)
    {
    if(x>=0) pointer.setX(x);
    if(y>=0) pointer.setY(y);
    }

  public void removeCircle(Circle circle)
    {
    super.removeState(circle);
    }
  public void removeCircle()
    {
    removeCircle(getSelected());
    if(getSelected()==getStart()) setStart(null);
    setSelected(null);
    }    
  public void setTransition(Transition t)
    {
    transition=t;
    }
  public Transition getTransition()
    {
    return transition;
    }
  public void unselectTransition()
    {
    transition=null;
    }
  public boolean selectTransition(String read)
    {
    Circle selected=getSelected();
    if(selected!=null)
      {
      transition=getTransition(selected,read);
      if(transition!=null) return true;
      }
    return false;
    }
  public void addOrSelectTransition(String read)
    {
    Circle selected=getSelected();
    if(selected!=null)
      {
      transition=getTransition(selected,read);
      if(transition==null)
        {
        transition=new Transition(selected,pointer,read,read,1,type);
        put(transition.getStart(),transition.getRead(),transition);
        }
      else
        {
        transition.setEnd(pointer);
        }
      }
    }
  public void setTransitionEnd(int x,int y)
    {
    if(transition!=null)
      {
      Circle c=getCircle(x,y);
      if(c==null) c=pointer;
      transition.setEnd(c);
      }
    }
  public void setTransitionEnd()
    {
    Circle selected=getSelected();
    if(selected!=null&&transition!=null) transition.setEnd(selected);
    }
  public void removeTransition(Transition t)
    {
    super.removeTransition(t);
    }
  public void removeTransition()
    {
    removeTransition(transition);
    transition=null;
    }    
  public void selectNextCircle()
    {
    if(transition!=null) setSelected((Circle)transition.getEnd());
    }
  public void tryToLock()
    {
    super.tryToLock(getSelected());
    }
  public int getType()
    {
    return type;
    }
  public void setType(int type)
    {
    this.type=type;
    }

  public void addCircle(String s)
    {
    String[] g=s.split("\t");
    int x=0;
    int y=0;
    if(g.length>=2) x=Integer.parseInt(g[1]);
    if(g.length>=3) y=Integer.parseInt(g[2]);
    addState(new Circle(g[0],x,y,R));
    }
  public void addTransition(String s)
    {
    String[] g=s.split("\t");
    addTransition(new Transition(getState(g[0]),getState(g[2]),g[1],g[3],g[4],type));
    }
  }
